# coding=utf-8
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from MSB_ERP.apps.erp_system.serializer.permission_serializer import PermissionsSerializer
from MSB_ERP.utils.base_views import MultipleDestoryMixin
from erp_system.models import PermissionsModel,RolesModel
import logging

logger = logging.getLogger('erp')

class PermissionsView(viewsets.ModelViewSet, MultipleDestoryMixin):
    '''
        create:
        权限--新增

        权限新增，status：201（成功），return:新增权限信息

        destroy:
        权限--删除单个权限

        权限删除，status：204（成功），return:None

        multiple_delete:
        权限--批量删除

        权限批量删除，status：204（成功），return:None

        update:
        权限--修改，权限本身的信息（属性），不包括授权（关联关系）

        权限修改，status：200（成功），return:修改增权限信息

        partial_update:
        权限--局部修改

        权限局部修改，status：200（成功），return:修改增权限信息

        list:
        权限--获得所有的权限

        find_permissions_by_menu:
        查询属于指定菜单或者接口的权限列表，需要传参：menu_id，比如：/find_permissions_by_menu?menu_id=2

        find_permissions:
        获取当前角色已经授权的权限ID列表和整个项目的所有权限（树形）列表，必传参数：rid（角色ID）

        例如：http://127.0.0.1:8000/permissions/find_permissions/?rid=2
        树形权限列表信息，status：200（成功），return：权限信息列表

        retrieve：
        查询某一个指定的权限信息

        查询指定ID的权限，status：200（成功），return：权限信息
    '''
    serializer_class = PermissionsSerializer  # 序列化（指明该视图在进行序列化或反序列化时使用的序列化器）
    queryset = PermissionsModel.objects.all() # 指明该视图集在查询数据时使用的查询集

    @action(methods=['get'],detail=False)
    def find_permissions_by_menu(self,request,*args,**kwargs):
        menu_id = request.query_params.get('menu_id')
        permissions_list = PermissionsModel.objects.filter(menu_id=menu_id).all()

        # 序列化
        ser = PermissionsSerializer(instance=permissions_list,many=True)
        return Response(ser.data) # 将数据转化出去

    @action(methods=['get'], detail=False)
    def find_permissions(self, request, *args, **kwargs):
        ''' 返回当前角色的所有已经拥有的权限ID列表，以及ERP系统中所有的权限（树形）数据 '''
        result = {} # 返回的整个字典

        rid = request.query_params.get('rid',None) # 接收数据
        if rid: # 查询当前角色的所有已经授权的ID

            # value指定我们要返回的字段（values返回的是一个字典，values_list返回的是一个列表），如果不接字段名字的话默认是以ID的
            # 返回角色所拥有的权限ID的字段
            # flat将数据进行扁平化，distinct数据去重操作
            # flat的影响：不写的话，数据库拿到的数据是 例：[(1,),(2,),(3,)]，写了话，数据库拿到的数据是 例：[1,3,5]，更方便前端进行操作
            ids = RolesModel.objects.filter(id=rid).values_list('permissions',flat=True).distinct()

            result['ids'] = ids # 把已经授权的ID列表存入返回字典中

        # 查询整个ERP系统中，所有的权限列表，要求是：要树形展示
        permission_list = PermissionsModel.objects.values('id','name','menu__name','menu__id','menu__parent__id')

        tree_dict = {} # 表示一个父节点
        tree_data = [] # 整个权限的树形数据

        # 第一步：构建一颗二级树（一级和二级之间用children来连接，二级和三级之间用permission来连接）
        # print(permission_list,'=========================================')
        for item in permission_list:
            # print(item,'==================================================')
            tree_dict[item['menu__id']] = item # 所有的菜单都放在字典里面去了
            # print(tree_dict,'===========')
        for i in tree_dict:
            if tree_dict[i]['menu__parent__id']: # 这是子菜单（二级）
                # print(tree_dict,tree_dict[i]['menu__parent__id'])
                ''' 这里的意思是在tree的第几位的menu__parent__id的值 '''
                pid = tree_dict[i]['menu__parent__id'] # 父菜单的ID
                # print(tree_dict[i])
                # print(tree_dict[i]['menu__parent__id'])
                parent = tree_dict[pid] # 父菜单
                child = dict() # 注册一个子菜单的字典
                child['mune__id'] = tree_dict[i]['menu__id'] # 给children（child的字典）的属性进行赋值
                child['mune__name'] = tree_dict[i]['menu__name']
                child.setdefault('permissions',[]) # 三级菜单并赋予一个列表，并取名为permissions
                # 把当前的二级（子菜单）关联到父菜单去
                parent.setdefault('children',[]).append(child) # 二级菜单并赋予一个列表，并取名为children
            else: # 所有的父菜单（一级）
                print(tree_dict[i])
                tree_data.append(tree_dict[i])
        # 第二步：在前面二级树形结构的基础上，添加子权限
        for parent in tree_data:
            if 'children' in parent: # 判断有没有二级树形
                for child in parent['children']:
                    # 得到child（二级）
                    for node in permission_list:
                        # 判断menu__parent__id是有值的和查看两个menu_id是不是一致的
                        # print("node:",node['menu__parent__id'])
                        # print(node['menu__id'])
                        # print(child['menu__id'])
                        if node['menu__parent__id'] and node['menu__id'] == child['mune__id']:
                            child['permissions'].append(node)
        result['tree_data'] = tree_data
        logger.info(tree_data)
        return Response(result)  # 将数据转化出去



